import type { AxiosInstance } from 'axios'
import axios from 'axios'
import mountInterceptors from './interceptors'
import type { RTRequestConfig, RTRequestInterceptors } from './requestTypes'

/**
 * 三层拦截器，全局、实例、方法
 */
export default class RTRequest {
  // 每次对象返回新的axios实例
  instance: AxiosInstance
  interceptors?: RTRequestInterceptors
  constructor (config: RTRequestConfig) {
    this.instance = axios.create(config)
    // 挂载拦截器，如果需要
    mountInterceptors(this, config)
  }

  request<T> (config: RTRequestConfig<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      // 执行单个方法的拦截器
      if (config.interceptors?.requestInterceptor) {
        config = config.interceptors.requestInterceptor(config)
      }
      this.instance
        // 在全局拦截器中设置返回的对象为 res.data，此时的 res 已经不再是 AxiosResponse 类型
        // 根据 request 请求源码可见返回的 res 类型可以根据泛型控制
        // 所以此处的 responseInterceptor 也需进行修改,需要层次渗透
        .request<any, T>(config)
        .then((res) => {
          if (config.interceptors?.responseInterceptor) {
            res = config.interceptors.responseInterceptor(res)
          }
          resolve(res)
        })
        .catch((err) => {
          reject(err)
          return err
        })
    })
  }

  get<T> (config: RTRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'GET' })
  }

  post<T> (config: RTRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'POST' })
  }

  delete<T> (config: RTRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'DELETE' })
  }

  patch<T> (config: RTRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'PATCH' })
  }
}
